home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 38 / Amiga Format CD38 (1999-03-15)(Future Publishing)(GB)(Track 1 of 3)[!][issue 1999-04].iso / -in_the_mag- / reader_requests / dice_v3.15 / lib / fd / open.c < prev    next >
C/C++ Source or Header  |  1999-01-26  |  4KB  |  179 lines

  1.  
  2. /*
  3.  *  OPEN.C
  4.  *
  5.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  6.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  7.  *    DICE-LICENSE.TXT.
  8.  */
  9.  
  10. #include <exec/types.h>
  11. #include <libraries/dos.h>
  12. #include <clib/dos_protos.h>
  13. #include <stdio.h>
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <fcntl.h>
  17. #include <errno.h>
  18. #include <lib/misc.h>
  19. #include <clib/dicecache_protos.h>
  20.  
  21. #ifndef UnixToAmigaPath
  22. #define UnixToAmigaPath(path)    path
  23. #endif
  24.  
  25. extern struct DosLibrary *DOSBase;
  26. extern struct Library *DiceCacheBase;
  27.  
  28. _IOFDS *
  29. _MakeFD(pfd)
  30. int *pfd;
  31. {
  32.     int fd;
  33.     _IOFDS *d;
  34.  
  35.     /*
  36.      *    extend limit if required
  37.      */
  38.  
  39.     for (fd = 0, d = _IoFD; fd < _IoFDLimit; ++fd) {
  40.     if ((d->fd_Flags & O_ISOPEN) == 0)
  41.         break;
  42.     ++d;
  43.     }
  44.     if (fd == _IoFDLimit) {
  45.     short newLimit = fd + 5;
  46.     _IOFDS *fds = malloc(sizeof(_IOFDS) * newLimit);
  47.     if (fds == NULL) {
  48.         errno = ENOMEM;
  49.         return(NULL);
  50.     }
  51.     _slow_bzero(fds, sizeof(_IOFDS) * newLimit);
  52.     _slow_bcopy(_IoFD, fds, sizeof(_IOFDS) * fd);
  53.     if (_IoFD != _IoStaticFD)
  54.         free(_IoFD);
  55.     _IoFD = fds;
  56.     _IoFDLimit = newLimit;
  57.     d = fds + fd;
  58.     }
  59.     if (d)
  60.     _slow_bzero(d, sizeof(*d));
  61.     *pfd = fd;
  62.     return(d);
  63. }
  64.  
  65.  
  66. int
  67. open(name, modes, ...)
  68. const char *name;
  69. int modes;
  70. {
  71.     int fd;
  72.     _IOFDS *d = _MakeFD(&fd);
  73.  
  74.     if (d == NULL)
  75.     return(-1);
  76.  
  77.     /*
  78.      *    If the cache is enabled attempt to open from the cache
  79.      */
  80.  
  81.     if (_DiceCacheEnable && (modes & (O_RDWR|O_WRONLY|O_APPEND|O_CREAT|O_TRUNC)) == O_RDONLY) {
  82.     void *cd;
  83.     long siz = 0;
  84.  
  85.     if (DiceCacheBase && (cd = DiceCacheOpen(name, "r", &siz))) {
  86.         _MakeCacheFD(d, cd, siz);
  87.         d->fd_Flags = modes | O_ISOPEN;
  88.         return(fd);
  89.     }
  90.  
  91.     /*
  92.      *  check error code.  If PS_LOCK_FAILED then it was a valid suffix
  93.      *  but the file does not exist.  There is no need for US to try
  94.      *  to lock the file *again*.  Since the suffix matched it isn't
  95.      *  a device and we don't have to try to Open().  In otherwords,
  96.      *  we save doing an extra Lock AND Open if DiceCache is enabled.
  97.      */
  98.  
  99.     if (siz == PS_LOCK_FAILED) {
  100.         errno = ENOFILE;
  101.         return(-1);
  102.     }
  103.     }
  104.  
  105.     /*
  106.      *    If we can't lock then be careful to call Open only once.  It
  107.      *    may be a new file that does not yet exist or a device file
  108.      */
  109.  
  110.     {
  111.     long lock = Lock(UnixToAmigaPath(name), SHARED_LOCK);
  112.     if (lock == NULL) {
  113. #ifdef NOTDEF
  114.         if (DOSBase->lib_Version >= 36) {
  115.         if (IsFileSystem(UnixToAmigaPath(name))) {
  116.             errno = ENOFILE;
  117.             return(-1);
  118.         }
  119.         }
  120.         /*
  121.         if (IoErr() == ERROR_DEVICE_NOT_MOUNTED) {
  122.         errno = ENOFILE;
  123.         return(-1);
  124.         }
  125.         */
  126. #endif
  127.         /*
  128.          *    file does not exist, open modes 1006 if create request, else
  129.          *    try to open modes 1005 (could be a non-file device)
  130.          */
  131.  
  132.         if (modes & O_CREAT)
  133.         d->fd_Fh = Open(UnixToAmigaPath(name), 1006);
  134.         else
  135.         d->fd_Fh = Open(UnixToAmigaPath(name), 1005);
  136.  
  137.         if (d->fd_Fh == NULL) {
  138.         errno = ENOFILE;
  139.         return(-1);
  140.         }
  141.         if (modes & O_APPEND)
  142.         Seek(d->fd_Fh, 0L, 1);
  143.         d->fd_Flags = modes | O_ISOPEN;
  144.         d->fd_FileName = strdup(name);
  145.         return(fd);
  146.     }
  147.     UnLock(lock);
  148.     }
  149.  
  150.     /*
  151.      *    Assume it is a normal file.. we can open/reopen it any
  152.      *    number of times.  Also, the file exists so...
  153.      */
  154.  
  155.     if ((modes & O_EXCL) && (modes & O_CREAT)) {
  156.     errno = EEXIST;
  157.     return(-1);
  158.     }
  159.     d->fd_Fh = Open(UnixToAmigaPath(name), ((modes & O_TRUNC) ? 1006 : 1005));
  160.  
  161.     if (d->fd_Fh == NULL && (modes & O_CREAT)) {
  162.     if (modes & O_EXCL) {
  163.         errno = ENOFILE;
  164.         return(-1);
  165.     }
  166.     d->fd_Fh = Open(UnixToAmigaPath(name), 1006);
  167.     }
  168.  
  169.     if (d->fd_Fh) {
  170.     if (modes & O_APPEND)
  171.         Seek(d->fd_Fh, 0L, 1);
  172.     d->fd_Flags = modes | O_ISOPEN;
  173.     d->fd_FileName = strdup(name);
  174.     return(fd);
  175.     }
  176.     return(-1);
  177. }
  178.  
  179.